package com.example.wyz.classplus.ui.custom;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.example.wyz.classplus.R;
import com.example.wyz.classplus.bean.Course;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 10153 on 2017/6/30.
 */

public class CoursesTable extends RelativeLayout {

    private OnItemClickListener mItemListener  = null;

    private final int[] colors = {
        getResources().getColor(R.color.colorCourse_1),
        getResources().getColor(R.color.colorCourse_2),
        getResources().getColor(R.color.colorCourse_3),
        getResources().getColor(R.color.colorCourse_4),
        getResources().getColor(R.color.colorCourse_5),
        getResources().getColor(R.color.colorCourse_6),
        getResources().getColor(R.color.colorCourse_7),
        getResources().getColor(R.color.colorCourse_8),
        getResources().getColor(R.color.colorCourse_9),
        getResources().getColor(R.color.colorCourse_10)
    };
    private int currentColorNum;

    private List<ArrayList<ArrayList<Integer>>> table = new ArrayList<>();
    private List<Course> coursesList = new ArrayList<>();
    private List<Course> coursesNeedToDraw = new ArrayList<>();
    private List<RectF> coursesRect = new ArrayList<>();
    private List<int[]> courseRects = new ArrayList<>();
    private List<String> courseString = new ArrayList<>();

    private int currentWeek;
    private int selectWeek;

    private float weight;
    private float height;
    private float perWeight;
    private float perHeight;

    private float downX;
    private float downY;
    private float upX;
    private float upY;
    private float touchX = -1;
    private float touchY = -1;
    private int selectedColumn = -1;
    private int selectedRow = -1;

    private Paint bgPaint;
    private Paint linePaint;
    private Paint selectedPaint;
    private Paint coursePaint;
    private TextPaint textPaint;


    public CoursesTable(Context context) {
        super(context);
        initView();
    }

    public CoursesTable(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public CoursesTable(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView(){
        setWillNotDraw(false);

        currentWeek = 2;
        selectWeek = 2;

        bgPaint = new Paint();
        bgPaint.setColor(Color.WHITE);
        bgPaint.setStyle(Paint.Style.FILL_AND_STROKE);

        linePaint = new Paint();
        linePaint.setColor(Color.GRAY);
        linePaint.setAlpha(50);

        selectedPaint = new Paint();
        selectedPaint.setColor(getResources().getColor(R.color.colorPrimary));
        selectedPaint.setAlpha(50);
        selectedPaint.setStyle(Paint.Style.FILL);
        selectedPaint.setAntiAlias(true);

        coursePaint = new Paint();
        coursePaint.setStyle(Paint.Style.FILL);
        coursePaint.setAntiAlias(true);

        textPaint = new TextPaint();
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(20);
        textPaint.setAntiAlias(true);


        for(int i = 0; i < 12; i++){
            ArrayList<ArrayList<Integer>> row = new ArrayList<>();
            for(int j = 0; j < 7; j++){
                row.add(new ArrayList<Integer>());
            }
            table.add(row);
        }
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        height = this.getMeasuredHeight();
        weight = this.getMeasuredWidth();
        perHeight = height / 12;
        perWeight = weight / 7;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        float currentHeight = perHeight;
        float currentWeight = perWeight;
        canvas.drawRect(0, 0, weight, height, bgPaint);

        for(int i = 0; i < 11; i++){
            canvas.drawLine(0, currentHeight, weight, currentHeight, linePaint);
            currentHeight += perHeight;
        }

        for(int i = 0; i < 6; i++){
            canvas.drawLine(currentWeight, 0, currentWeight, height, linePaint);
            currentWeight += perWeight;
        }
        drawCourses(canvas);
        drawSelectedBlock(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_CANCEL:
                initSelectedBlock();
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                upX = event.getX();
                upY = event.getY();
                if(Math.abs(upX-downX) < 10 && Math.abs(upY-downY) < 10){
                    touchX = downX;
                    touchY = downY;

                    int row = 0;
                    int column = 0;
                    while (column * perWeight < touchX){
                        column++;
                    }
                    while (row * perHeight < touchY){
                        row++;
                    }
                    if(table.get(row-1).get(column-1).size() == 0){
                        if(selectedRow == row &&selectedColumn == column){
                            onClickBlock(column, row);
                        }else {
                            selectedRow = row;
                            selectedColumn = column;
                        }
                    }else {
                        initSelectedBlock();
                        if(this.mItemListener != null){
                            mItemListener.OnItemClick(table.get(row-1).get(column-1));
                        }
                    }
                }else {
                    initSelectedBlock();
                }
                invalidate();
                break;
            default:
                break;
        }
        return true;
    }

    private void drawSelectedBlock(Canvas canvas){
        if(touchX > 0 && touchY > 0 && selectedRow > 0 && selectedColumn > 0){
            if(table.get(selectedRow-1).get(selectedColumn-1).size() == 0){
                float left = (selectedColumn-1) * perWeight;
                float top = (selectedRow-1) * perHeight;
                float right = selectedColumn * perWeight;
                float bottom = selectedRow * perHeight;
                canvas.drawRect(left, top, right, bottom, selectedPaint);
            }
        }
    }

    private void drawCourses(Canvas canvas){
        for(int i = 0; i < coursesNeedToDraw.size(); i++){
            int [] duration = coursesNeedToDraw.get(i).getDuration();
            if(selectWeek < duration[0] || selectWeek > duration[1]){
                coursePaint.setColor(Color.LTGRAY);
                textPaint.setColor(Color.DKGRAY);
            }else {
                coursePaint.setColor(coursesNeedToDraw.get(i).getColor());
                textPaint.setColor(getResources().getColor(R.color.colorWhite));

            }
            coursePaint.setAlpha(150);
            //canvas.drawRect(coursesRect.get(i),coursePaint);
            int [] para = courseRects.get(i);
            RectF rectF = new RectF((perWeight*para[0])+2, perHeight*para[1]+2,
                                   perWeight*para[2]-2, perHeight*para[3]-2);
            canvas.drawRoundRect(rectF, 15, 15, coursePaint);
            canvas.save();

            canvas.translate(perWeight*para[0] + (perWeight / 2), perHeight*para[1]+10);
            StaticLayout staticLayout = new StaticLayout(courseString.get(i), textPaint, (int)(perWeight-8),
                                                         Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
            staticLayout.draw(canvas);
            canvas.restore();
        }
    }

    private void onClickBlock(int column, int row){
        Toast.makeText(this.getContext(), "click: "+column+" , "+row, Toast.LENGTH_SHORT).show();
    }

    private void initSelectedBlock(){
        touchX = -1;
        touchY = -1;
        selectedRow = -1;
        selectedColumn = -1;
    }

    public void initCourses(List<Course> courses){
        this.coursesList.addAll(courses);
        currentColorNum = 0;

        Course mCourse;
        int mWeek;
        int [] mPeriod;
        ArrayList<Integer> idList;

        for(int i = 0; i < coursesList.size(); i++){
            mCourse = coursesList.get(i);
            mWeek = mCourse.getWeek();
            mPeriod = mCourse.getPeriod();
            boolean isNeedToDraw = true;

            for(int j = mPeriod[0] - 1; j < mPeriod[1]; j++){
                idList = new ArrayList<>(table.get(j).get(mWeek-1));
                if (idList.size() != 0){
                    isNeedToDraw = false;
                }
                table.get(j).get(mWeek-1).add(mCourse.getCourseID());
            }

            if(isNeedToDraw){
                int left = (mWeek - 1);
                int top = (mPeriod[0] - 1);
                int right = mWeek;
                int bottom = mPeriod[1];
                courseRects.add(new int[]{left, top, right, bottom});

                if(mCourse.getColor() == -1){
                    boolean hasSameCourse = false;
                    for(Course dCourse: coursesNeedToDraw){
                        Log.d("CourseTable", "initCourses: has same?");
                        if(mCourse.isSameFrom(dCourse)){
                            Log.d("CourseTable", "initCourses: has same");
                            mCourse.setColor(dCourse.getColor());
                            hasSameCourse = true;
                            break;
                        }
                    }
                    if(!hasSameCourse){
                        Log.d("CourseTable", "initCourses: "+currentColorNum);
                        mCourse.setColor(colors[currentColorNum]);
                        currentColorNum++;
                    }
                }
                String str;
                if(mCourse.getClassroom().equals("")){
                    str = mCourse.getCourseName();
                }else {
                    str = mCourse.getCourseName()+"@"+mCourse.getClassroom();
                }
                courseString.add(str);
                coursesNeedToDraw.add(mCourse);
            }
        }
    }

    public void setSelectWeek(int week){
        Log.d("CourseTable", "initCourses: ");
        this.selectWeek = week;
        invalidate();
    }

    public void setOnItemListener(OnItemClickListener mListener){
        this.mItemListener = mListener;
    }

    public interface OnItemClickListener{
        void OnItemClick(List<Integer> idList);
    }
}
